package com.boarsoft.config.file;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.annotation.PostConstruct;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.boarsoft.common.util.FileUtil;
import com.boarsoft.config.core.ConfigFileListener;
import com.boarsoft.config.server.ConfigServerService;

/**
 * 此类在message-server启动时，从message-web获取队列监息，实现队列的动态加载和列新
 * 
 * @author Mac_J
 *
 */
public class DynaFileConfiger {
	private Logger log = LoggerFactory.getLogger(this.getClass());

	/** 本地配置文件变更事件监听器 */
	protected Map<String, ConfigFileListener> configListenerMap;
	/** 远程的配置文件查询服务 */
	protected ConfigServerService configServerSvc;
	/** 当前应用的appId */
	protected String appId;
	/** 当前环境，由环境变量传入 */
	protected String env;
	/** 实例分组，由环境变量传入 */
	protected String group = "default";

	@PostConstruct
	public void init() throws IOException {
		List<ConfigFile> lt = null;
		try {
			// 先测试message-web是否可用
			if (!configServerSvc.test()) {
				return;
			}
			// 从远程查询当前所用到的所有的配置文件
			lt = configServerSvc.getConfigFiles(appId, env, group);
			// 清理本地目录
			for (Entry<String, ConfigFileListener> en : configListenerMap.entrySet()) {
				String k = en.getKey();
				ConfigFileListener cl = en.getValue();
				String ap = cl.getAbosultePath();
				File df = new File(ap);
				log.warn("Config listener {} clear directory {}", k, ap);
				FileUtil.deleteContents(df, cl.getFileFilter());
			}
		} catch (Exception e) {
			log.warn("Can not load config from remote");
			log.debug("Error on load config from remote: {}/{}/{}", appId, env, group, e);
		}
		// 如果没有任何文件，后面不用执行
		if (lt == null || lt.isEmpty()) {
			return;
		}
		// 如果可用，则删除本地已有的文件
		for (ConfigFile f : lt) {
			ConfigFileListener cl = this.getConfigListener(f.getCode());
			String n = cl.getAbosultePath(f.getDeployPath());
			byte[] ba = f.getContent();
			if (ba == null) {
				continue;
			}
			log.warn("Write config file {} with {} bytes", n, ba.length);
			// 写入文件并通知listener加载
			FileUtil.writeBytes(new File(n), ba);
			cl.onReady(f.getDeployPath());
		}
	}

	protected ConfigFileListener getConfigListener(String code) {
		if (configListenerMap.containsKey(code)) {
			return configListenerMap.get(code);
		}
		return configListenerMap.get("default");
	}

	public Map<String, ConfigFileListener> getConfigListenerMap() {
		return configListenerMap;
	}

	public void setConfigListenerMap(Map<String, ConfigFileListener> configListenerMap) {
		this.configListenerMap = configListenerMap;
	}

	public ConfigServerService getConfigServerSvc() {
		return configServerSvc;
	}

	public void setConfigServerSvc(ConfigServerService configServerSvc) {
		this.configServerSvc = configServerSvc;
	}

	public String getAppId() {
		return appId;
	}

	public void setAppId(String appId) {
		this.appId = appId;
	}

	public String getEnv() {
		return env;
	}

	public void setEnv(String env) {
		this.env = env;
	}

	public String getGroup() {
		return group;
	}

	public void setGroup(String group) {
		this.group = group;
	}
}